#ifndef _VR_VRML_TYPES_
#define _VR_VRML_TYPES_
#include "vrNode.h"

#define NAME_LEN 256

// Standard atomic types
#define SFBOOL 1
#define SFCOLOR 2
#define SFFLOAT 3
#define SFIMAGE 4
#define SFINT32 5
#define SFNODE 6
#define SFROTATION 7
#define SFSTRING 8
#define SFTIME 9
#define SFVEC2F 10
#define SFVEC3F 11
#define MFCOLOR 13
#define MFFLOAT 14
#define MFINT32 15
#define MFNODE 16
#define MFROTATION 17
#define MFSTRING 18
#define MFVEC2F 19
#define MFVEC3F 20

typedef union{
	char id[NAME_LEN];
	int int32;
	float float_val;
	VRSFTime time_val;
	float vec2f[2];
	float vec3f[3];
	float vec4f[4];
	VRSFBool sf_bool;
	VRNode* sf_node;
	VRMFInt32* mf_int32;
	VRMFFloat* mf_float;
	VRMFVec2f* mf_vec2f;
	VRMFVec3f* mf_vec3f;
	VRMFRotation* mf_rotation;
	VRMFString* mf_string;
	VRMFColor* mf_color;
	VRMFNode* mf_node;
} WRLSTYPE;

typedef enum {
	VRFIELD_EXPOSED, 
	VRFIELD_NOTEXPOSED, 
	VRFIELD_EVENTIN, 
	VRFIELD_EVENTOUT
} VRFieldScope;

class ProtoArg{
public:
	int type;
	WRLSTYPE default_val;

	ProtoArg();
	ProtoArg(int tp);
	~ProtoArg();
	void set_default_param(WRLSTYPE* what);
};

class VRParseField{
public:
	char name[NAME_LEN];
	int type_index; // index of the field type in "all_types"
	VRFieldScope scope;
	ProtoArg* field_update_info;
	VRParseField(char* nm,int tp,int is_it_basic_type=1);
	~VRParseField();
};

class VRParseType{
public:
	char name[NAME_LEN];           // "SFBool" ... "Group" ,"Appearance" ,..."MyProto"
	int type; // SFBool ... SFNode
	int field_num;
	int size;
	VRParseField** fields;

	VRNode* body;

	VRParseType(char* nm);
	VRParseType(char* nm,int tp);
	~VRParseType();
	int add_field(VRParseField* fld);
	VRParseField* find_field(char* nm);
	int find_field_idx(char* nm);
};

class VRProtoCall:public VRNode{
public:
	WRLSTYPE** actual_args;
	int actual_arg_num;
	VRParseType* proto_info;
	VRProtoCall();
	VRProtoCall(VRParseType* protoheader);
	void copy(VRProtoCall*);
	void release();
	~VRProtoCall();
	void set_actual_arg(int field_idx,int type,WRLSTYPE* actual_val);
};


//--------------------------------------------------
// Different nodes/fields cleanup functions
//--------------------------------------------------
void delete_mfstring(VRMFString* data);
void delete_mfnode(VRMFNode* data);
void delete_mfint32(VRMFInt32* data);
void delete_mffloat(VRMFFloat* data);
void delete_mfvec2f(VRMFVec2f* data);
void delete_mfvec3f(VRMFVec3f* data);
void delete_mfrotation(VRMFRotation* data);
void delete_mfcolor(VRMFColor* data);
void delete_sfnode(VRNode* data);

void clean_parser_value(WRLSTYPE* v);
void delete_parser_value(int type,WRLSTYPE* v);
void copy_parser_value(int type,WRLSTYPE* to,WRLSTYPE* from);
void update_field_value(VRParseType* node_type,VRParseField* field,VRNode* current_vr_struct,WRLSTYPE* field_val);

#endif // _VR_VRML_TYPES_
